/*
   ______   ______
  /\__  __\/\ \___\
  \/_/\ \_/\ \ \__/    __   __     __
     \ \ \  \ \ \__\  /\ \ /\ \  /'__`\
     _\_\ \  \ \ \_/_ \ \ \\_\ \/\  __/
    /\____/   \ \_____\\ \_____/\ \____\
    \_/__/     \/_____/ \/____/  \/____/

 	This file is part of the JEVE core API.

    JEve is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    JEve is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Copyright 2008 JEve Project (JEveProject@gmail.com)
 */
package be.fomp.jeve.core.config;

import be.fomp.jeve.core.exceptions.JEveConfigurationException;
import be.fomp.jeve.core.exceptions.JEveConfigurationInitializationException;
import be.fomp.jeve.core.util.Proxy;
import java.net.Proxy.Type;
import java.util.Properties;
import java.util.Map;

/**
 * <pre>
 *  ______   ______
 * /\__  __\/\ \___\
 * \/_/\ \_/\ \ \__/    __   __     __
 *    \ \ \  \ \ \__\  /\ \ /\ \  /'__`\
 *    _\_\ \  \ \ \_/_ \ \ \\_\ \/\  __/
 *   /\____/   \ \_____\\ \_____/\ \____\
 *   \_/__/     \/_____/ \/____/  \/____/
 *</pre>
 *	This file is part of the JEVE core API.<br />
 *	<br />
 *
 * Implementation of AbstractJeveConfiguration and CoreConfiguration
 * This class is used for retrieving and storing the configuration settings.
 *
 * @author Sven Meys
 *
 */
public final class CoreConfigurationImpl extends AbstractJEveConfiguration implements CoreConfiguration {

	/**
	 * This constructor calls super() by default.
	 * When the configuration file exists it will be read into the properties object.
	 * When it doesn't exist, the program will attempt to create a default configuration file
	 * which can be altered afterwards.
	 *
	 * @throws JEveConfigurationInitializationException If the config file does not exist and creating one failed.
	 * @throws JEveConfigurationException If reading from the configuration file failed.
	 */
	public CoreConfigurationImpl() throws JEveConfigurationException{}

	public final String getConfigFileName() {
		return CONFIG_FILE_NAME;
	}

	public final Properties getConfigurationProperties() {
		return CORE_PROPERTIES;
	}

	
	public final Proxy getProxyConfiguration() {

		Proxy returnValue = null;

		//Loading properties
		Properties properties = getConfigurationProperties();
		
		String useProxy =     properties.getProperty(USE_PROXY,  DEFAULT_USE_PROXY);
		String proxyType =    properties.getProperty(PROXY_TYPE, DEFAULT_PROXY_TYPE);
		String proxyHost =    properties.getProperty(PROXY_HOST, DEFAULT_PROXY_HOST);
		String proxyPort =    properties.getProperty(PROXY_PORT, DEFAULT_PROXY_PORT);
		String useProxyAuth = properties.getProperty(PROXY_AUTH, DEFAULT_PROXY_AUTH);
		String username =     properties.getProperty(PROXY_USER, DEFAULT_PROXY_USER);
		String password =     properties.getProperty(PROXY_PASS, DEFAULT_PROXY_PASS);

		//Setting standard values if config file values are invalid...
		//FIXME optimize these checks.. ugly code
		if (useProxy == null || !"true".equals(useProxy)) {
			useProxy = DEFAULT_USE_PROXY;
		}

		if (proxyType == null || (!"DIRECT".equals(proxyType) && !"HTTP".equals(proxyType) && !"SOCKS".equals(proxyType))) {
			proxyType = DEFAULT_PROXY_TYPE;
		}
		if (proxyHost == null) {
			proxyHost = ""+DEFAULT_PROXY_HOST;
		}
		if (proxyPort == null || !proxyPort.matches("[0123456789]+")) {
			proxyPort = DEFAULT_PROXY_PORT;
		}
		if (useProxyAuth == null || !"true".equals(useProxyAuth)) {
			useProxyAuth = DEFAULT_PROXY_AUTH;
		}
		if (username == null) {
			username = DEFAULT_PROXY_USER;
		}
		if (password == null) {
			password = DEFAULT_PROXY_PASS;
		}

		//Returning the right object
		if ("true".equalsIgnoreCase(useProxy)) {
			if ("true".equalsIgnoreCase(useProxyAuth)) {
				//Authentication enabled
				returnValue = new Proxy(Type.valueOf(proxyType), proxyHost, Integer.parseInt(proxyPort), username, password);
			} else {
				//Authentication disabled
				returnValue = new Proxy(Type.valueOf(proxyType), proxyHost, Integer.parseInt(proxyPort));
			}
		}
		return returnValue;
	}

	
	public final void setProxyconfiguration(boolean useProxy, Type proxyType, String proxyHost, int proxyPort,

											boolean useProxyAuth, String proxyUser, String proxyPass) throws JEveConfigurationException {
		//FIXME use defaults or throw exception?
		// Setting default values if null or invalid
		if (proxyType == null) {
			proxyType = Type.valueOf(DEFAULT_PROXY_TYPE);
		}
		if (proxyHost == null) {
			proxyHost = DEFAULT_PROXY_HOST;
		}
		if (proxyPort <= 0) {
			proxyPort = Integer.valueOf(DEFAULT_PROXY_PORT);
		}
		if (proxyUser == null) {
			proxyUser = DEFAULT_PROXY_USER;
		}
		if (proxyPass == null) {
			proxyPass = DEFAULT_PROXY_PASS;
		}

		//Setting the properties
		Properties properties = getConfigurationProperties();

		properties.setProperty(USE_PROXY, "" + useProxy);
		properties.setProperty(PROXY_TYPE, proxyType.toString());
		properties.setProperty(PROXY_HOST, proxyHost);
		properties.setProperty(PROXY_PORT, "" + proxyPort);
		properties.setProperty(PROXY_AUTH, "" + useProxyAuth);
		properties.setProperty(PROXY_USER, proxyUser);
		properties.setProperty(PROXY_PASS, proxyPass);
	}

	public String toString() {
		StringBuilder returnValue = new StringBuilder();
		Properties properties = getConfigurationProperties();

		for(Map.Entry<Object, Object> entry: properties.entrySet()){
			 returnValue.append(String.format("%s=%s\n",entry.getKey(),entry.getValue()));
		}
		return returnValue.toString();
	}
}
